from parser import get_node_list, get_node_tree
from source import FileSource


def render_include_nodes(include_list, **kwargs):
    if kwargs.get('context'):
        context = kwargs['context']
    else:
        context = {}
    for item in include_list:
        node = item[0]
        node.build()
        if node.tag == 'IncludeNode':
            node.content = render_from_file(node.filename, context=context)


def render_extends_nodes(extends_node, **kwargs):
    if kwargs.get('context'):
        context = kwargs['context']
    else:
        context = {}
    for node in extends_node:
        node.content = render_extends_node(node, context)


def get_block_by_name(root_node, block_name):
    for node in root_node.child_nodes:
        if node.tag != 'BlockNode':
            continue
        node.build()
        if node.block_name == block_name:
            return node
        if len(node.child_nodes) > 0:
            result = get_block_by_name(node, block_name)
            if result:
                return result
    return None


def render_extends_node(extends_node, context):
    src = FileSource()
    src.open(extends_node.filename)
    node_list, include_list = get_node_list(src)
    render_include_nodes(include_list, context=context)
    node_tree, extends_list = get_node_tree(node_list)
    # replace block
    i = 0
    while i < len(extends_node.child_nodes):
        new_node = extends_node.child_nodes[i]
        if new_node.tag != 'BlockNode':
            i += 1
            continue
        new_node.build()
        base_node = get_block_by_name(node_tree, new_node.block_name)
        base_node.child_nodes = new_node.child_nodes
        i += 1
    render_extends_nodes(extends_list, context=context)
    return node_tree.render(context=context)


def render_from_str(src, **kwargs):
    if kwargs.get('context'):
        context = kwargs['context']
    else:
        context = {}
    node_list, include_list = get_node_list(src)
    render_include_nodes(include_list, context=context)
    node_tree, extends_list = get_node_tree(node_list)
    render_extends_nodes(extends_list, context=context)
    return node_tree.render(context=context)


def render_from_file(path, **kwargs):
    if kwargs.get('context'):
        context = kwargs['context']
    else:
        context = {}
    src = FileSource()
    src.open(path)
    return render_from_str(src, context=context)